package SinaBot;
use strict;
#use Data::Dumper;
use WWW::Mechanize;
use WWW::Mechanize::GZip;
use Tools qw/ sayinf sayerr /;

our %typenum = (
    'follow'=>0,
    'fans'=>1,
);

our %t_sina_regulars = (
    'page_total_num'=>'<em>(\d+)</em></a>\s+<a\s+class="btn_num\s+btn_numWidth"',
    'user_block'=>'(<li\s+?class="MIB_linedot_l".*?</li>)',
    'user_block_search'=>'(<li\s+?class="MIB_linedot2".*?</li>)',
    'user_id'=>'<img.+?title=.+?uid="(\d+)".+?src="\S+?"',
    'my_id'=>'\$uid\s+:\s*"(\d+)"',
    'my_verify_vip' => 'vipBtnbg',
    'my_org_blog' => '<p\s+class="sms"\s+mid="\d+"\s+type="1">',
    'my_sex_area' => '<div\s+class="ad\s+MIB_txtbl">\s+<img\s+title="(\S+?)".+?>\s+(\S+?)</div>',
    'my_name' => '<div\s+class="name\s+MIB_txtal">\s*<span\s+class="lf">(\S+?)\s*<',
    'my_fansnum' => '<div\s+class="f_pro">\s+<div\s+class="title\s+font_14\s+MIB_linkcr"><a\s+href="\S+?">\S+?\((\d+)\)'
);

####################### MAIN CLASS #########################

sub do_new{
    my ($class,@args) = @_;

    #my ($useremail,$username) = @args;
    my $mech = WWW::Mechanize::GZip->new( stack_depth=>30,timeout => 15 );
    $mech->agent_alias('Linux Mozilla');
    #$mech->cookie_jar(HTTP::Cookies->new(file=>"lwpcookies.txt",autosave=>1));
    my $head = HTTP::Headers->new(
        'Accept'=>'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language'=>'zh-cn,zh;q=0.5',
        'Accept-Encoding'=>'gzip,deflate',
        'Accept-Charset'=>'gb2312,utf-8;q=0.7,*;q=0.7',
        'Keep-Alive'=>'300',
        'Connection'=>'keep-alive',
        'Content-Type'=>'application/x-www-form-urlencoded;charset=UTF-8'
    );

    my $loginname;
    my $password;
    my $id;
    my $your_userid;
    my $your_type;

    my $max_page = 1;
    my $current_page = -1;
    my $page_inc = 1;

    my $self = bless{
        'mech' => $mech,
        'head' => $head,

        'id' => $id,
        'loginname' => $loginname,
        'password' => $password,
        
        'your_userid' => $your_userid,
        'your_type' => $your_type,
        'max_page' => $max_page,
        'current_page' => $current_page,
        'page_inc' => $page_inc,
    },$class;
}

sub do_logout{
    my ($self) = @_;
}

sub _do_get{
    my ($self,$url,$args) = @_;

    my $req;
    if ($args){
        $req = HTTP::Request->new('POST',$url,$self->{'head'},$args);
    }else{
        $req = HTTP::Request->new('GET',$url,$self->{'head'});
    }
    my $res = $self->{'mech'}->request($req);
    #if (!$res->is_success) 
    #{
        #$res->status_line;
        #$res->as_string;
    #}
    sayinf "[Getting url] ".$url;
    #sleep 1;
    return $res->content;
}

sub get_myip{
    my ($self) = @_;
    my $_url = "http://www.ip138.com/ip2city.asp";
    my $_content = $self->_do_get($_url);
    
    my $_mstr = '\[(.*)\]';
    if($_content =~ m{$_mstr}gsix){
        return $1;
    }else{
        return $_content;
    }
}   

sub do_start_grep{
    #if the type has zero people, how to deal with?
    my ($self,$type,$userid) = @_;
    
    if(!$userid){
        $userid = $self->{'id'};
    }

    $self->{'your_userid'} = $userid;
    $self->{'your_type'} = $type;
    my $_url="http://t.sina.com.cn/".$userid."/".$type;
    my $_content = $self->_do_get($_url);
    #------------get max page num----------------------------
    $self->{'max_page'} = 1;
    my $_mstr = $t_sina_regulars{'page_total_num'};
    if( $_content =~ m{$_mstr}six){
        $self->{'max_page'} = $1;
    }
    sayinf '[ '.$userid.' ] has ('.$self->{'max_page'}.') pages of ['.$type.']' ;
    #--------------------------------------------------------
    $self->{'current_page'} = -1;
    $self->{'page_inc'} = 1;
}

sub _do_get_one_user_id{
    my ($self,$content) = @_;
    my $_mstr = $t_sina_regulars{'user_id'};
    if ($content =~ m{$_mstr}six){
        return $1;
    }
}


sub _get_first_page
{
    my ($self) = @_;
    my $_firstpage = ($self->{'page_inc'} == 1)?1:$self->{'max_page'};
}
sub _get_last_page
{
    my ($self) = @_;
    my $_firstpage = ($self->{'page_inc'} == 1)?$self->{'max_page'}:1;
}

sub set_reverse_order {
    my ($self,$normal) = @_;
    if(!$normal) {
        $self->{'page_inc'} = -1;
    }else{
        $self->{'page_inc'} = 1;
    }
    $self->{'current_page'} = -1;
}

sub get_if_first_grab {
    my ($self) = @_;

    return $self->{'current_page'} == $self->_get_first_page;
}

sub do_get_onepage{
    my ($self) = @_;

    my @users;
    
    if ($self->{'current_page'} == -1 ){
        $self->{'current_page'} = $self->_get_first_page;
    }elsif( $self->{'current_page'}!=$self->_get_last_page) {
        $self->{'current_page'} += $self->{'page_inc'};    
    }else{
        return @users;
    }
    my $_type_num = $typenum{$self->{'your_type'}};
    my $_url = "http://t.sina.com.cn/attention/att_list.php?action=".$_type_num."&uid=".$self->{'your_userid'}."&page=".$self->{'current_page'}; 
    my $_content = $self->_do_get($_url);
    my $_mstr = $t_sina_regulars{'user_block'};
    while($_content =~ m{$_mstr}gsix){
        push (@users,$self->_do_get_one_user_id($1));
    }
    sayinf 'Get ('.($#users+1).') user ';
    return @users;
}

sub do_get_onepage_search{
    my($self,$word) = @_;
    my @users;
    my $_url = "http://t.sina.com.cn/k/$word";
    my $_content = $self->_do_get($_url);
    my $_mstr = $t_sina_regulars{'user_block_search'};
    while($_content =~ m{$_mstr}gsix){
        push (@users,$self->_do_get_one_user_id($1));
    }
    sayinf 'Get ('.($#users+1).') user ';
    return @users;
}

sub do_login{
    my ($self,$loginname,$password) = @_;

    $self->{'loginname'} = $loginname;
    $self->{'password'} = $password;

    my $_url = 'http://login.sina.com.cn/sso/login.php';
    my $_args = 'username='.$loginname.'&password='.$password;

    if($self->_do_get($_url,$_args)){
        sayinf "login success!";
    }else{
        die "can't login!";
    }
    #my $_content = $self->_do_get("http://t.sina.com.cn");
    #my $_mstr = $t_sina_regulars{'my_id'};
    #if($_content =~ m{$_mstr}six){
        #$self->{'id'} = $1;
        #sayinf '[get id '.$self->{'id'}.']';
    #}else{
        #die "can't fatch the id!";
    #}
}

sub set_inf{
    my ($self,$id) = @_;
    $$self{'id'} = $id;
}

sub check_user{
	my ($self,$userid) = @_;
	my %res;	
	my $_url = 'http://t.sina.com.cn/'.$userid;
	if(my $_content = $self->_do_get($_url)){
		my $_mstr = $t_sina_regulars{'my_verify_vip'};
		if($_content =~ m{$_mstr}six){
			$res{'vip_verify'} = 1;
		}else{
			$res{'vip_verify'} = 0;
		}

		my $org_blog_num = 0;
		$_mstr = $t_sina_regulars{'my_org_blog'};
		while ($_content =~ m{$_mstr}gsix){
			$org_blog_num ++;
		}
		$res{'org_blog_num'} = $org_blog_num;

		$_mstr = $t_sina_regulars{'my_name'};
		if($_content =~ m{$_mstr}six){
			$res{'name'} = $1;
		}

		$_mstr = $t_sina_regulars{'my_sex_area'};
		if($_content =~ m{$_mstr}six){
			$res{'sex'} = $1;
			$res{'area'} = $2;
		}

	    $_mstr = $t_sina_regulars{'my_fansnum'};
		if($_content =~ m{$_mstr}six){
			$res{'fans_num'} = $1;
		}

		if(not $res{'name'}){$res{'name'}='unknown';}
		if(not $res{'sex'}){$res{'sex'}='unknown';}
		if(not $res{'area'}){$res{'area'}='unknown';}
		if(not $res{'fans_num'}){$res{'fans_num'}=0;}

		return \%res;
	}
}

sub unfollow {
    my ($self, $userid) = @_;

    my $_url = 'http://t.sina.com.cn/attention/aj_delfollow.php';
    my $_args = "touid=$userid&fromuid=$$self{'id'}";
    
    if (my $_content = $self->_do_get($_url,$_args))
    {
        return $self->_check_unfollow($_content, $userid);
    }
    return 1;
}

sub follow {
    my ($self, $userid) = @_;
    
    my $_url = 'http://t.sina.com.cn/attention/aj_addfollow.php';
    my $_args = "uid=$userid&fromuid=$$self{'id'}";

    if (my $_content = $self->_do_get($_url,$_args))
    {
        return $self->_check_follow($_content, $userid);
    }
    return 9;
}

sub _check_unfollow {
    my ($self,$content,$id) = @_;
    if($content =~/{"code":"A00006"}/){
        sayinf "successfuly unfollowed $id";
        return 0;
    }
    elsif($content =~/MR0050/){
      sayerr "Captcha .... (id=$id)";
    }
    elsif($content =~/R01440/){
      sayerr "Account Limit (500/day) Reached (id=$id)";
    }
    elsif($content =~/M05002/){
      sayerr "Account Limit (2000/account) Reached (id=$id)";
    }
    elsif($content =~/{"code":"M02016"}/i){
      sayerr "Account Limit (500/account) Reached (error 2) (id=$id)";
      return 5;
    }
    else{
      sayerr "unkonwn error (id=$id)";
      sayerr $content;
    }
    return 9;
}

sub _check_follow {
    my ($self,$content,$id) = @_;
    if( $content =~ m{<li\s*class="MIB_linedot_l".*?<div class="conBox_l"><a href="http://t.sina.com.cn/$id">.*?<span\s*class="add_yet"></span>已关注</a></p>.*?</li>}six){
    sayinf "successfuly followed long one $id";
    return 0;
    }elsif($content =~/{"code":"A00006"}/){
      sayinf "successfuly followed $id";
      return 0;
    }
    elsif($content =~/MR0050/){
      sayerr "Captcha ....";
      return 1;
    }
    elsif($content =~/M00003/){
      sayerr "Account error!!";
      return 4;
    }
    elsif($content =~/R01440/){
      sayerr "Account Limit (500/day) Reached";
      return 5;
    }
    elsif($content =~/M05002/){
      sayerr "Account Limit (2000/account) Reached";
      return 6;
    }
    else{
      sayerr "unkonwn error";
      sayerr $content;
      return 9
    }
}

sub new_blog{
    my($self,$content,$pic) = @_;
    if($self->_do_get("http://t.sina.com.cn")){
    }
    sleep(1);
    if($self->_do_get("http://t.sina.com.cn/mblog/publish.php?rnd=0.33880882644945887","content=".$content."&pic=".$pic."&styleid=1&retcode=")){
    }
    sleep(1);
}

1;

